package PoolThread;

import Queues.ObjectFIFO;





// uses class ObjectFIFO from chapter 18  

public class ThreadPoolWorker {  

	private static int nextWorkerID = 0;  
	private ObjectFIFO idleWorkers;  

	private int workerID;  

	private ObjectFIFO handoffBox;  



	private Thread internalThread;  

	private volatile boolean noStopRequested;  


	public ThreadPoolWorker(ObjectFIFO idleWorkers) {  

		this.idleWorkers = idleWorkers;  



		workerID = getNextWorkerID();  

		handoffBox = new ObjectFIFO(1); // only one slot  



		// just before returning, the thread should be created.  

		noStopRequested = true;  



		Runnable r = new Runnable() {  

			public void run() {  

				try {  

					runWork();  

				} catch ( Exception x ) {  

					// in case ANY exception slips through  

					x.printStackTrace();  

				}  

			}  

		};  



		internalThread = new Thread(r);  

		internalThread.start();  

	}  



	public static synchronized int getNextWorkerID() {  

		// notice: sync�d at the class level to ensure uniqueness  

		int id = nextWorkerID;  

		nextWorkerID++;  

		return id;  

	}  


	public void process(Runnable target) throws InterruptedException {  

		handoffBox.add(target);  

	}  



	private void runWork() {  
		while ( noStopRequested ) {  

			try {  

			//	System.out.println("IDdespachador=" + workerID +", Listo para Iniciar a trabajar");  

				// Worker is ready work. This will never block  

				// because the idleWorker FIFO queue has  

				// enough capacity for all the workers.  

				idleWorkers.add(this);  



				// wait here until the server adds a request  
				Runnable r = (Runnable) handoffBox.remove();  


				System.out.println("IDdespachador=" + workerID +", Iniciando la ejecuci�n de un nuevo Runnable: " + r);  

				runIt(r); // catches all exceptions  

			} catch ( InterruptedException x ) {  

				Thread.currentThread().interrupt(); // re-assert  

			}  

		}  
	}  



	private void runIt(Runnable r) {  

		try {  
			r.run();  
		} catch ( Exception runex ) {  

			// catch any and all exceptions  

			System.err.println("Uncaught exception fell through from run()");  

			runex.printStackTrace();  

		} finally {  

			// Clear the interrupted flag (in case it comes back  

			// set) so that if the loop goes again, the  

			// handoffBox.remove() does not mistakenly  

			// throw an InterruptedException.  

			Thread.interrupted();  

		}  

	}  



	public void stopRequest() {  

		System.out.println("IDdespachador=" + workerID +", stopRequest() recibida.");  

		noStopRequested = false;  

		internalThread.interrupt();  

	}  



	public boolean isAlive() {  

		return internalThread.isAlive();  

	}  

} 

